using Godot;
using System;
using System.Collections.Generic;

namespace PaintAWorld.Gd
{
	public partial class DialogManager : Control
	{
		private Client _client = null;
		public Client Client => _client;
		private Stack<Dialog> _dialogStack = new();

		public bool Displaying => _dialogStack.Count > 0;

		public Action StartDisplay;
		public Action AllDialogClosed;

		public void Setup(Client client)
		{
			_client = client;
		}

		public override void _Input(InputEvent e)
		{
			if (!Displaying) return;

			if (e is InputEventKey ke && ke.Pressed)
			{
				switch (ke.Keycode)
				{
					case Key.Escape:
						RemoveDialog();
						AcceptEvent();
						break;
				}
			}
		}

		public void AddDialog(Dialog dialog)
		{
			if (_dialogStack.Count == 0)
			{
				MouseFilter = MouseFilterEnum.Stop;
				StartDisplay?.Invoke();
			}

			dialog.BindManager(this);

			AddChild(dialog);
			_dialogStack.Push(dialog);
		}

		public void AddDialog(PackedScene sceneRes) => AddDialog(sceneRes.Instantiate<Dialog>());

		public void ReplaceDialog(Dialog dialog)
		{
			if (_dialogStack.Count > 0)
			{
				var dialogOld = _dialogStack.Pop();

				dialogOld.UnbindManager();
				// RemoveChild(dialogOld);
				dialogOld.QueueFree();
			}

			AddDialog(dialog);
		}

		public void ReplaceDialog(PackedScene sceneRes) => ReplaceDialog(sceneRes.Instantiate<Dialog>());

		public void RemoveDialog()
		{
			if (_dialogStack.Count == 0)
			{
				GD.PushWarning("Trying to remove dialog in a empty manager.");
				return;
			}

			var dialog = _dialogStack.Pop();

			dialog.UnbindManager();
			// RemoveChild(dialog);
			dialog.QueueFree();

			if (_dialogStack.Count == 0)
			{
				MouseFilter = MouseFilterEnum.Ignore;
				AllDialogClosed?.Invoke();
			}
		}
	}
}